package de.gof.ppstool.core.produktion;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import de.gof.ppstool.fertigungsverwaltung.db.Fertigungsauftrag;
import de.gof.ppstool.fertigungsverwaltung.db.Fertigungsauftragsposition;
import de.gof.ppstool.kundenauftragsverwaltung.IKundenauftragsverwaltung;
import de.gof.ppstool.kundenauftragsverwaltung.db.Kundenauftrag;
import de.gof.ppstool.lagerverwaltung.ILagerverwaltung;
import de.gof.ppstool.util.GOFException;
import de.gof.ppstool.util.export.Output;
import de.gof.ppstool.util.export.ProductionItem;

/**
 * Bestimmt die Losgroessen und die Reihenfolge der Produktionsauftraege 
 */
@Service(LosplanungNewDeineMudda.NAME)
@Transactional
public class LosplanungNewDeineMudda {
	public static final String NAME = "losplanung";
	private List<ProductionItem> pil = new ArrayList<ProductionItem>();
	private Output output = Output.getInstance();
	private Fertigungsauftrag fa = null;
	private String teile;
	@Autowired
	private IKundenauftragsverwaltung kv;
	@Autowired
	private ILagerverwaltung lv;
	private Kundenauftrag kundenauftrag = null;
	private List<String> reihenfolge_fahrraeder = new ArrayList<String>();
	private List<Fertigungsauftragsposition> teile_mit_null_lagerbestand = new ArrayList<Fertigungsauftragsposition>();
	private List<Fertigungsauftragsposition> teile_mit_niedrigem_lagerbestand = new ArrayList<Fertigungsauftragsposition>();
	private List<Fertigungsauftragsposition> restliche_teile = new ArrayList<Fertigungsauftragsposition>();
	private List<Fertigungsauftragsposition> teile_am_ende = new ArrayList<Fertigungsauftragsposition>();
	private String teileListe = "";
	private Integer herstellMengeTeil1 = -1;
	private Integer herstellMengeTeil2 = -1;
	private Integer herstellMengeTeil3 = -1;
	private String restliche_teile_raeder = "";

	/**
	 * Ermittelt die optimale Produktionsreihenfolge
	 * @param fertigungsauftrage
	 * @throws GOFException  
	 */
	public void ermittleReihenfolge(List<Fertigungsauftrag> fertigungsauftrage,
			String periode) throws GOFException {
		//Neuen Auftrag (fa) erzeugen
		erzeugeSummiertenFertigungsauftrag(fertigungsauftrage);
		//aktuellen Kundenauftrag holen
		getKundenauftrag(periode);
		//Teile mit Lagerbestand=0 und <=50 ermitteln
		//Teile bei denen wir die Auftragsmenge schon auf Lager haben
		HashMap<String, Double> verhaeltnisMap = new HashMap<String, Double>();
		Integer lagerbestand_tmp_teil1 = -1;
		Integer lagerbestand_tmp_teil2 = -1;
		Integer lagerbestand_tmp_teil3 = -1;
		Double verhaeltnis_teil1 = 0.0;
		Double verhaeltnis_teil2 = 0.0;
		Double verhaeltnis_teil3 = 0.0;
		for (Fertigungsauftragsposition fap : fa
				.getFertigungsauftragspositionen()) {
			teileListe += ";" + fap.getTeil().getTeilId().toString() + ";";
			//Debug
			//System.out.println(fap.getTeil().getTeilId() + ":" + fap.getAuftragsmenge());
			if (fap.getAuftragsmenge() < 0)
				System.err
						.println("Herstellmenge < 0 -> Fehler im Produktionsplan? (Teil: "
								+ fap.getTeil().getTeilId() + ")");

			if (fap.getTeil().getTeilId().equals(Long.valueOf(1))) {
				if (herstellMengeTeil1 == -1)
					herstellMengeTeil1 = fap.getAuftragsmenge();

				lagerbestand_tmp_teil1 = lv
						.findeTeilNachTeilId(Long.valueOf(1)).getLagerbestand();
				verhaeltnis_teil1 = (double) lagerbestand_tmp_teil1
						/ fap.getAuftragsmenge();
				verhaeltnisMap.put("teil1", verhaeltnis_teil1);
				if (lagerbestand_tmp_teil1 >= fap.getAuftragsmenge()) {
					teile_am_ende.add(fap);
					continue;
				}

			}

			if (fap.getTeil().getTeilId().equals(Long.valueOf(2))) {
				if (herstellMengeTeil2 == -1)
					herstellMengeTeil2 = fap.getAuftragsmenge();

				lagerbestand_tmp_teil2 = lv
						.findeTeilNachTeilId(Long.valueOf(2)).getLagerbestand();
				verhaeltnis_teil2 = (double) lagerbestand_tmp_teil2
						/ fap.getAuftragsmenge();
				verhaeltnisMap.put("teil2", verhaeltnis_teil2);
				if (lagerbestand_tmp_teil2 >= fap.getAuftragsmenge()) {
					teile_am_ende.add(fap);
					continue;
				}

			}

			if (fap.getTeil().getTeilId().equals(Long.valueOf(3))) {
				if (herstellMengeTeil3 == -1)
					herstellMengeTeil3 = fap.getAuftragsmenge();

				lagerbestand_tmp_teil3 = lv
						.findeTeilNachTeilId(Long.valueOf(3)).getLagerbestand();
				verhaeltnis_teil3 = (double) lagerbestand_tmp_teil3
						/ fap.getAuftragsmenge();
				verhaeltnisMap.put("teil3", verhaeltnis_teil3);
				if (lagerbestand_tmp_teil3 >= fap.getAuftragsmenge()) {
					teile_am_ende.add(fap);
					continue;
				}

			}

			//Alle Teile bei denen der Lagerbestand > Auftragsmenge ist werden in die Ende liste geadded
			if (fap.getTeil().getLagerbestand() >= fap.getAuftragsmenge()) {
				teile_am_ende.add(fap);
			} else if (fap.getTeil().getLagerbestand() == 0) {
				teile_mit_null_lagerbestand.add(fap);
			} else if (fap.getTeil().getLagerbestand() <= 50) {
				teile_mit_niedrigem_lagerbestand.add(fap);
			} else {
				restliche_teile.add(fap);
				if (fap.getTeil().getTeilId().toString().equals("1"))
					restliche_teile_raeder += ";1;";

				if (fap.getTeil().getTeilId().toString().equals("2"))
					restliche_teile_raeder += ";2;";

				if (fap.getTeil().getTeilId().toString().equals("3"))
					restliche_teile_raeder += ";3;";

			}

		}
		// falls ein Fahrrad noch nicht in der VerhaeltnisMap drin ist
		if (!(verhaeltnisMap.size() == 3)) {
			if (verhaeltnis_teil1 == 0.0) {
				verhaeltnisMap.put("teil1", 1.0);
			}

			if (verhaeltnis_teil2 == 0.0)
				verhaeltnisMap.put("teil2", 1.0);

			if (verhaeltnis_teil3 == 0.0)
				verhaeltnisMap.put("teil3", 1.0);

		}

		//Pruefung welches Rad zuerst hergestellt wird
		sortHashMapByValuesD(verhaeltnisMap);
		//wird in reihenfolge_fahrraeder geschrieben
		//reihenfolge fahrraeder durchgehen
		//		System.out.println("Startlaenge: " +teileListe.length());
		//		System.out.println(teileListe);
		//		System.out.println("Size teile_mit_null_lagerbestand: "+teile_mit_null_lagerbestand.size());
		//		System.out.println("Size teile_mit_niedrigem_lagerbestand: "+teile_mit_niedrigem_lagerbestand.size());
		//		System.out.println("Size restliche_teile: "+restliche_teile.size());
		//		System.out.println("Size teile_am_ende: "+teile_am_ende.size());
		List<Integer> score = new ArrayList<Integer>();
		score.add(teile_mit_null_lagerbestand.size());
		score.add(teile_mit_niedrigem_lagerbestand.size());
		score.add(restliche_teile.size());
		score.add(teile_am_ende.size());
		int tmp = -100000;
		for (int i = 0; i < score.size(); i++) {
			if (i > tmp)
				tmp = i;

		}
		while (teileListe.length() != 0) {
			for (String i : reihenfolge_fahrraeder) {
				if (Integer.parseInt(i) == 1) {
					int zaehler = 0;
					while (zaehler <= tmp) {
						if (teile_mit_null_lagerbestand.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									teile_mit_null_lagerbestand);

						if (teile_mit_niedrigem_lagerbestand.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									teile_mit_niedrigem_lagerbestand);

						if (restliche_teile.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									restliche_teile);

						//if(teile_am_ende.size() > 0) reihenfolgeTeil(Integer.parseInt(i), teile_am_ende);
						//System.out.println(1);
						zaehler++;
					}
				}

				if (Integer.parseInt(i) == 2) {
					int zaehler = 0;
					while (zaehler <= tmp) {
						if (teile_mit_null_lagerbestand.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									teile_mit_null_lagerbestand);

						if (teile_mit_niedrigem_lagerbestand.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									teile_mit_niedrigem_lagerbestand);

						if (restliche_teile.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									restliche_teile);

						//if(teile_am_ende.size() > 0) reihenfolgeTeil(Integer.parseInt(i), teile_am_ende);
						//System.out.println(2);
						zaehler++;
					}
				}

				if (Integer.parseInt(i) == 3) {
					int zaehler = 0;
					while (zaehler <= tmp) {
						if (teile_mit_null_lagerbestand.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									teile_mit_null_lagerbestand);

						if (teile_mit_niedrigem_lagerbestand.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									teile_mit_niedrigem_lagerbestand);

						if (restliche_teile.size() > 0)
							reihenfolgeTeil(Integer.parseInt(i),
									restliche_teile);

						//if(teile_am_ende.size() > 0) reihenfolgeTeil(Integer.parseInt(i), teile_am_ende);
						//System.out.println(3);
						zaehler++;
					}
				}

			}
			while (teileListe.length() > 0) {
				for (String i : reihenfolge_fahrraeder) {
					if (teile_mit_null_lagerbestand.size() > 0)
						reihenfolgeTeil(Integer.parseInt(i),
								teile_mit_null_lagerbestand);

					if (teile_mit_niedrigem_lagerbestand.size() > 0)
						reihenfolgeTeil(Integer.parseInt(i),
								teile_mit_niedrigem_lagerbestand);

					if (restliche_teile.size() > 0)
						reihenfolgeTeil(Integer.parseInt(i), restliche_teile);

					if (teile_am_ende.size() > 0)
						reihenfolgeTeil(Integer.parseInt(i), teile_am_ende);

				}
			}
			//System.out.println(teileListe);
			//System.out.println("Restlaenge " +teileListe.length());
		}
		//Liste in Output singleton schreiben
		output.setProduktionsliste(null);
		output.setProduktionsliste(pil);
	}

	/**
	 * Reihenfolgeplanung je Radtyp
	 * @param i
	 */
	@SuppressWarnings("unchecked")
	private void reihenfolgeTeil(Integer i,
			List<Fertigungsauftragsposition> fapl) {
		/* Teil1
		 13,18,7,49,4,10,50,17,16,51,26,1			
		 */
		if (i.intValue() == 1) {
			int zaehler = -1;
			Iterator iterator = fapl.iterator();
			while (iterator.hasNext()) {
				Fertigungsauftragsposition fap = (Fertigungsauftragsposition) iterator
						.next();
				zaehler++;
				if (fap.getTeil().getTeilId().equals(Long.valueOf(13))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(18))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(7))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(49))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(4))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(10))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(50))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(17))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(16))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(51))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(26))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(1))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

			}
		}

		/*  Teil2:
		 14,19,8,54,5,11,55,17,16,56,26,2
		 */
		if (i.intValue() == 2) {
			int zaehler = -1;
			Iterator iterator = fapl.iterator();
			while (iterator.hasNext()) {
				Fertigungsauftragsposition fap = (Fertigungsauftragsposition) iterator
						.next();
				zaehler++;
				if (fap.getTeil().getTeilId().equals(Long.valueOf(14))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(19))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(8))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(54))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(5))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(11))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(55))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(17))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(16))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(56))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(26))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(2))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

			}
		}

		/*			
		 Teil3:
		 15,20,9,29,6,12,30,17,16,31,26,3
		 */
		if (i.intValue() == 3) {
			int zaehler = -1;
			Iterator iterator = fapl.iterator();
			while (iterator.hasNext()) {
				Fertigungsauftragsposition fap = (Fertigungsauftragsposition) iterator
						.next();
				zaehler++;
				if (fap.getTeil().getTeilId().equals(Long.valueOf(15))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(20))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(9))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(29))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(6))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(12))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(30))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(17))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(16))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(31))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(26))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

				if (fap.getTeil().getTeilId().equals(Long.valueOf(3))) {
					Integer restmenge = erzeugeTeilOutput(fap, fapl);
					if (restmenge.intValue() > 0)
						fapl.get(zaehler).setAuftragsmenge(restmenge);

					if (restmenge.intValue() == 0) {
						zaehler--;
						iterator.remove();
						continue;
					}

				}

			}
		}

	}

	private Integer erzeugeTeilOutput(Fertigungsauftragsposition fap,
			List<Fertigungsauftragsposition> fapl) {
		if (fap.getAuftragsmenge() == 0) {
			teileListe = teileListe.replace(";"
					+ fap.getTeil().getTeilId().toString() + ";", "");
			return 0;
		}

		Integer menge = 0;
		if (fap.getAuftragsmenge() >= 50)
			menge = 50;
		else
			menge = fap.getAuftragsmenge();

		addToOutput(fap, menge);
		fap.setAuftragsmenge((fap.getAuftragsmenge() - menge));
		if (fap.getTeil().getTeilId().intValue() == 1)
			herstellMengeTeil1 -= menge;

		if (fap.getTeil().getTeilId().intValue() == 2)
			herstellMengeTeil2 -= menge;

		if (fap.getTeil().getTeilId().intValue() == 3)
			herstellMengeTeil3 -= menge;

		if (fap.getAuftragsmenge() == 0) {
			teileListe = teileListe.replace(";"
					+ fap.getTeil().getTeilId().toString() + ";", "");
			return 0;
		}

		return fap.getAuftragsmenge();
	}

	/**
	 * Erzeugt aus der Liste einen neuen Fertigungsauftrag mit einer Fertigungsauftragsposition je zu produzierendes Teil
	 * @param fertigungsauftrage
	 * @throws GOFException  
	 */
	private void erzeugeSummiertenFertigungsauftrag(
			List<Fertigungsauftrag> fertigungsauftrage) throws GOFException {
		teile = "";
		fa = new Fertigungsauftrag();
		List<Fertigungsauftragsposition> fap_list = new ArrayList<Fertigungsauftragsposition>();
		//Neue Fertigungsposition fuer jedes zu produzierende Teil erzeugen (1 Position je Teil mit der Gesamtmenge)	
		for (Fertigungsauftrag fa_tmp : fertigungsauftrage) {
			for (Fertigungsauftragsposition fap : fa_tmp
					.getFertigungsauftragspositionen()) {
				if (!teile.contains(";" + fap.getTeil().getTeilId().toString()
						+ ";")) {
					teile += ";" + fap.getTeil().getTeilId().toString() + ";";
					Fertigungsauftragsposition fap_neu = new Fertigungsauftragsposition();
					fap_neu.setTeil(fap.getTeil());
					fap_neu.setAuftragsmenge(fap.getAuftragsmenge());
					fap_neu.setFertigungsauftrag(fa);
					if (fap.getAuftragsmenge() > 0)
						fap_list.add(fap_neu);

					if (fap.getAuftragsmenge() < 0)
						throw new GOFException(
								"Komische Sachen vom Produktionsplan: Auftragsmenge <0!");

				} else {
					for (Fertigungsauftragsposition fap_x : fap_list) {
						if (fap_x.getTeil().getTeilId()
								.equals(fap.getTeil().getTeilId())) {
							fap_x.setAuftragsmenge(fap_x.getAuftragsmenge()
									+ fap.getAuftragsmenge());
						}

					}
				}

			}
		}
		fa.setFertigungsauftragspositionen(fap_list);
	}

	/**
	 * Fuegt ein Los dem Output hinzu 
	 * @param fa
	 * @param amount 	 
	 */
	private void addToOutput(Fertigungsauftragsposition fap, Integer amount) {
		pil.add(new ProductionItem(fap.getTeil().getTeilId().intValue(), amount));
	}

	private void getKundenauftrag(String periode) throws GOFException {
		Kundenauftrag ka = kv.findeKundenauftragNachBemerkung(periode);
		if (ka != null) {
			kundenauftrag = ka;
		} else {
			throw new GOFException("Fehler: Kundenauftrag nicht gefunden");
		}

	}

	/**
	 * Sortiert eine Hashmap
	 * @param passedMap
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public LinkedHashMap sortHashMapByValuesD(HashMap passedMap) {
		List mapKeys = new ArrayList(passedMap.keySet());
		List mapValues = new ArrayList(passedMap.values());
		Collections.sort(mapValues);
		Collections.sort(mapKeys);
		LinkedHashMap sortedMap = new LinkedHashMap();
		Iterator valueIt = mapValues.iterator();
		while (valueIt.hasNext()) {
			Object val = valueIt.next();
			Iterator keyIt = mapKeys.iterator();
			while (keyIt.hasNext()) {
				Object key = keyIt.next();
				String comp1 = passedMap.get(key).toString();
				String comp2 = val.toString();
				if (comp1.equals(comp2)) {
					passedMap.remove(key);
					mapKeys.remove(key);
					sortedMap.put((String) key, (Double) val);
					String tmp = (String) key;
					reihenfolge_fahrraeder.add(tmp.substring(4));
					break;
				}

			}
		}
		return sortedMap;
	}

	public void setKundenauftrag(Kundenauftrag kundenauftrag) {
		this.kundenauftrag = kundenauftrag;
	}

	public Kundenauftrag getKundenauftrag() {
		return kundenauftrag;
	}

}
